
#include <stdio.h>
#include <stdlib.h>

#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <vector>
#include <windows.h>


using namespace std;


typedef struct inputfilecsv {
    char* from;
    char* to;
} inputfilecsv;


typedef struct {
    int index;
    char *name;
} Columns_csv;



typedef struct job_transform_columns {
    char* name;
    char* operation;
    char* mode;
    char* separated;
    char* inputfilename;
    vector<inputfilecsv> rows;
} job_transform_columns;


typedef struct job_transform {

//char* source;
//char* hostip;
//int* port;
char* inputfile;
char* outputfile;
vector<job_transform_columns> cols;
//char* execute;
//int* order;

} job_transform;



vector<string>
get_cvs_line( const char *line, char *separated, char *delimiter){

    vector<string> array_cols;
    //int Flag_separated=0;
    int Flag_delimit=0;

    string value_continue;
    string gg;

    for(int i=0; i<strlen(line);i++){

        if( Flag_delimit ){

            if(line[i] == delimiter[0]){
                Flag_delimit=0;
                //value_continue=value_continue+line[i];
                array_cols.push_back(value_continue);
                value_continue="";
            }else{
                value_continue=value_continue+line[i];
            }

        }else{

            if(line[i] == delimiter[0]){
                Flag_delimit=1;
                //value_continue=line[i];
            }else{

                if(line[i] == separated[0]){
                    if(value_continue!="")
                        array_cols.push_back(value_continue);

                    value_continue="";
                }else{

                   if(i+1==strlen(line)){
                        value_continue=value_continue+line[i];
                        array_cols.push_back(value_continue);
                   }else{
                        value_continue=value_continue+line[i];
                   }

                }

            }

        }


    }

//
//    for( int i=0; i< array_cols.size();i++){
//
//        cout<<array_cols.at(i)<<endl;
//    }

    return array_cols;

}



vector<inputfilecsv>
get_csv_from_to( char *inputfilename, char *separated ){

    vector<inputfilecsv> inputfile_csv;

    try{

        ifstream inputfile;

        inputfile.open(inputfilename);

        if(inputfile.good()){

            string line = "";
            int i=0;
            string word = "";

            char *delimiter="\"";
            //char *separated=",";

            //char separated_=*separated;//[strlen(separated)];
            //memcpy(separated_,separated,strlen(separated));

            while (getline(inputfile, line)){

                stringstream strstr(line);

                word = "";
                i=0;
                inputfilecsv inputfile_csvItem;

                vector<string> csv_cols;

                const char *text = line.c_str();

                csv_cols = get_cvs_line( text, separated, delimiter );

                for(int j=0; j<csv_cols.size();j++){
                    word=csv_cols.at(j);

                //while (getline(strstr,word, separated_)){

                    char *aux=new char[word.size()];
                        //aux[word.size()]=0;
                    memcpy(aux,word.c_str(),word.size());
                    aux[word.size()]='\0';

                    if(i==0)
                        inputfile_csvItem.from=aux;
                    else{
                        inputfile_csvItem.to=aux;
                        break;
                    }

                    i++;
                }

                inputfile_csv.push_back(inputfile_csvItem);
            }

        }else{
            throw "erro ao abrir o arquivo.";
        }


        inputfile.close();

    }catch(exception &e)  // intercept OTL exceptions
	{
        //cout<<" error "<<e.getMessage()<<endl;
        //cerr <<"Erro: "<< e.what() << '\n';
        throw e.what();
		//throw "Can't use letters";

	}

	return inputfile_csv;

}


int
get_index_column_from_name( vector<Columns_csv> cols, char *name ){
//char *p=new char[1024];
    int result=-1;

    for(int i=0; i<cols.size();i++ )
        if( strcmp( cols.at(i).name, name) ==0){
            result= cols.at(i).index;
            break;
        }

    return result;
}

char *
replace(char *s, char old, char novo)
{
	char *p = s;

	while(*p)
	{
		if(*p == old)
			*p = novo;

		++p;
	}

	return s;
}


int
isNumeric( char *text ){

    if(strlen(text)<1)
        return -1;

    for(int i=0;i<strlen(text);i++)
        if (isalpha(text[i]))
            return -1;

    return 1;

}


bool isNumber(string line)
{
    return (atoi(line.c_str()));
}


void
starting_job_transformation(job_transform job){

    //job_transform* job = (job_transform*)pointer;

    //cout<<"inputfilename"<<job.inputfilename<<endl;
    //cout<<"outputfile"<<job.outputfile<<endl;


    try{

        ofstream outputfile;
        ifstream inputfile;

        inputfile.open(job.inputfile);
        outputfile.open(job.outputfile);

        if(inputfile.good()){

            if(outputfile.good()){

                string line = "";
                vector<Columns_csv> cols;
                //int total = job.cols.size();
                vector<inputfilecsv> inputfile_csv;//total];
                int i=0;
                string word = "";
                int IndexColumn=0;
                int CountColumns=0;
                int FlagWrite=0;
                int FlagCol=0;
                int FlagRow=0;
                int FlagSeparated=0;

                char *delimiter="\"";
                char *separated=",";
                int Flag_metadata=0;

                while (getline(inputfile, line)){

                    stringstream strstr(line);

                    if(!Flag_metadata)
                        if(line!=""){
                            outputfile<<line<<"\n";
                            continue;
                        }else{
                            Flag_metadata=1;
                            outputfile<<"\n";
                            continue;
                        }


                    word = "";
                    IndexColumn=0;
                    FlagWrite=0;
                    FlagCol=0;
                    FlagRow=0;
                    FlagSeparated=0;


                    vector<string> csv_cols;

                    const char *text = line.c_str();

                    csv_cols = get_cvs_line( text, separated, delimiter );

                    for(int j=0; j<csv_cols.size();j++){
                        word=csv_cols.at(j);
                    //while (getline(strstr,word, ',')){


                        if(i==0){

                            Columns_csv colcsv;
                            colcsv.index=IndexColumn;

                            char *a=new char[word.size()+1];
                            a[word.size()]=0;
                            memcpy(a,word.c_str(),word.size());

                            colcsv.name=a;
                            cols.push_back(colcsv);

                            if(!FlagCol){//FlagRow==0
                                FlagCol=1;
                            }else
                                outputfile <<",";

                            outputfile <<a;

                        }else{

//                            for(int x=0; x< job.cols.size();x++){
//                                for(int w=0; w< job.cols.at(x).rows.size();w++){
//                                    cout<<"form="<<job.cols.at(x).rows.at(w).from<<", to="<<job.cols.at(x).rows.at(w).to<<endl;
//                                }
//                            }

//for(int f=0;f<cols.size();f++){
//
//    cout<<"cols="<<cols.at(f).name<<endl;
//}

                            for(int z=0;z<job.cols.size();z++){

                                if( get_index_column_from_name(cols,
                                        job.cols.at(z).name)==IndexColumn){

                                    if( strcmp( job.cols.at(z).mode, "csv")==0){

                                        if( strcmp( job.cols.at(z).operation,
                                            "encoding")==0){

                                            //for(int x=0; x< job.cols.size();x++){
                                                for(int w=0; w< job.cols.at(z).rows.size();w++){
                                                    //cout<<"form="<<job.cols.at(z).rows.at(w).from<<", to="<<job.cols.at(z).rows.at(w).to<<endl;
                                                    char *a=new char[word.size()+1];
                                                    a[word.size()]=0;
                                                    memcpy(a,word.c_str(),word.size());

                                                    if(strcmp( job.cols.at(z).rows.at(w).from,
                                                              a)==0){
                                                              //cout<<"sim"<<endl;
                                                        if(!FlagSeparated){//FlagRow==0
                                                            FlagSeparated=1;
                                                        }else
                                                            outputfile <<job.cols.at(z).separated;
                                                        //char *m=job.cols.at(z).rows.at(w).to;

                                                        if( isNumber(job.cols.at(z).rows.at(w).to) ){
                                                            outputfile <<job.cols.at(z).rows.at(w).to;
                                                        }else{
                                                            outputfile <<delimiter<<job.cols.at(z).rows.at(w).to<<delimiter;
                                                        }

                                                        FlagRow=1;
                                                    }

                                                }
                                            //}

                                        }

                                    }


                                }

                            }

                            if(!FlagRow){//FlagRow==0
                                //FlagRow=1;
                                if(!FlagSeparated){//FlagRow==0
                                    FlagSeparated=1;
                                }else
                                    outputfile <<",";

                                //char *m=word.c_str();


                                //outputfile <<delimiter<<word<<delimiter;
                                if( isNumber(word) ){
                                    outputfile <<word;
                                }else{
                                    outputfile <<delimiter<<word<<delimiter;
                                }

                            }else{

                            }


                            FlagRow=0;

                        }


                        //if(!FlagRow){//FlagRow==0
                        //        //FlagRow=1;
                        //    outputfile<<"\n";
                        //}else


                        IndexColumn++;


                    }
                    //cout<<endl;
                    i++;
                    outputfile<<"\n";

                }

            }else{
                throw "Erro ao escrever o arquivo";
            }

        }else{
            throw "erro ao abrir o arquivo.";
        }

        inputfile.close();
        outputfile.close();

    }catch(exception &e)  // intercept OTL exceptions
	{
        //cout<<" error "<<e.getMessage()<<endl;
        //cerr <<"Erro: "<< e.what() << '\n';
        throw e.what();
		//throw "Can't use letters";

	}









//    for(int i=0;i<job.cols.size();i++){
//        //char *v;
//
//        //v= job.cols.at(i).name;
//
//
//        cout<<"name"<<job.cols.at(i).name<<endl;
//
//
//        cout<<"separated"<<job.cols.at(i).separated<<endl;
//
//        cout<<"operation"<<job.cols.at(i).operation<<endl;
//
//        cout<<"mode"<<job.cols.at(i).mode<<endl;
//
//        cout<<"inputfilename"<<job.cols.at(i).inputfilename<<endl;
//
//    }

}





int main(int argc, char* argv[])
{

char *text= "1,\"a\",\"jose,m,m,m,m e maria\",2013";
//char *delimiter = new char[1];
char *delimiter="\"";
//char *separated =  new char[1];
char *separated=",";

//vector<string> rs;

//rs = get_cvs_line(text,separated, delimiter );



    //system("etm-core.exe \"Decrypted Text.txt\"");
    //execlp("notepad", "-c", "\"Decrypted Text.txt\"", NULL);

    job_transform job_item;

        //currentPath = (char*)malloc(sizeof(char)*strlen(argv[0]));

        //strcpy(currentPath,argv[0]);

        //currentPath=ExtractFilePath(currentPath,SEPARATE_DIR);


    if( argc>1){

        //char* outfilename;
       // outfilename = (char*)malloc(sizeof(char)*
                               // (strlen(currentPath)+1024));

        for(int i=0; i<argc;i++){

            //cout<<"argv["<<i<<"]="<<argv[i]<<"\n"<<endl;
            //char* p;
            //p=(char*)malloc(sizeof(char)*strlen(argv[i]));

            if(strcmp(argv[i],"-inputfile")==0){
                job_item.inputfile=argv[i+1];
            //}else if(strcmp(argv[i],"-separated")==0){
            //    job_item.separated=argv[i+1];
            }else if(strcmp(argv[i],"-outputfile")==0){
                job_item.outputfile=argv[i+1];//outfilename;
                //free(outfilename);
            }else if(strcmp(argv[i],"-columns")==0){

                job_transform_columns cols;
                //int y=i
                for(int y=i; y<argc;y++){
//cout<<argv[y]<<endl;

                    if(strcmp(argv[y],"-name")==0){
                        cols.name=argv[y+1];
                    }else if(strcmp(argv[y],"-operation")==0){
                        cols.operation=argv[y+1];
                    }else if(strcmp(argv[y],"-mode")==0){
                        cols.mode=argv[y+1];
                    }else if(strcmp(argv[y],"-separated")==0){
                        cols.separated=argv[y+1];
                    }else if(strcmp(argv[y],"-inputfilename")==0){
                        cols.inputfilename=argv[y+1];

                        vector<inputfilecsv> csv;
                        csv=get_csv_from_to( cols.inputfilename,
                                                cols.separated);
                        cols.rows=csv;
                        break;
                    }

                }

//                cols.name=argv[i+2];
//                cols.separated=argv[i+3];
//                cols.operation=argv[i+4];
//                cols.mode=argv[i+5];
//                cols.inputfilename=argv[i+6];

                job_item.cols.push_back(cols);

            }

            //cout<<"argv["<<i<<"]="<<argv[i]<<""<<endl;
        }

        starting_job_transformation(job_item);

//        cout<<"separated "<<job_item.separated<<"\n"<<endl;
//        cout<<"outputfile "<<job_item.filename<<"\n"<<endl;
//        cout<<"query "<<job_item.query<<"\n"<<endl;
//        cout<<"odbc "<<job_item.odbc<<"\n"<<endl;



        cout<<job_item.outputfile<<endl;//<<" currentPath="<<currentPath<<endl;
        cout<<"ok"<<endl;

    }else{

//        job_item.odbc="UID=postgres;PWD=postgres;DSN=postgres";
//        job_item.separated=",";
//         char* outfilename;
//                 outfilename = (char*)malloc(sizeof(char)*
//                                (strlen(currentPath)+1024)
//                                   );
//                wsprintf(outfilename,"%s%s",currentPath, "e-big_date.txt");
//                job_item.filename=outfilename;
//                //free(outfilename);
//
//        job_item.filename=outfilename;
//        job_item.query="SELECT id, description, detail, year FROM big_date limit 5000";
//
//        otl_query(&job_item);

        //cout<<"sem argv\n"<<endl;

    }


    system("pause");

    exit(0);




    ifstream infile("C:\\workspace\\c\\etm-transform\\bin\\Release\\e-big_date.txt");
    string line = "";

    vector<Columns_csv> cols;

    //vector<string> all_words;
    //cout << "Hello";
    int i=0;


    while (getline(infile, line))
    {



        stringstream strstr(line);
        string word = "";
        //char *word2=NULL;
        int n=0;

        //word2=(char*)malloc(sizeof(char)*1024);

        while (getline(strstr,word, ','))
        {

            if(i==0)
            {

                if(n==0)
                {
                    cout<<word;
                }
                else
                {
                    cout<<","<<word;
                }


                //colcsv = (Columns_csv*)malloc(sizeof(Columns_csv)*1);

                //word2=(char*)word.c_str();
//colcsv.index = (int*)malloc(sizeof(int)*10);
                //colcsv.index = (int*)malloc(sizeof(int)*10);
               //strcpy( colcsv.index, n);
                Columns_csv colcsv;

                colcsv.index=n;

                char *a=new char[word.size()+1];
                a[word.size()]=0;
                memcpy(a,word.c_str(),word.size());

                colcsv.name=a;

                cols.push_back(colcsv);


//cout<<"======================================"<<cols.at(0).name<<endl;
//exit(0);

            }
            else
            {

//for(int y=0;y<cols.size();y++){
//
//    Columns_csv colcsv;
//    colcsv = cols.at(y);
//
//    cout<<"y="<<y<<", name="<<colcsv.index<<endl;
//}

//cout<<"======================================"<<cols.at(2).index<<endl;


                if( get_index_column_from_name(cols, "detail")==n){


                    cout<<"index="<<"------"<<endl;
                }


                if(n==0)
                {
                    cout<<word;
                }
                else
                {
                    cout<<","<<word;
                }
            }
            n++;
            //cout<<word<<endl;
            //all_words.push_back(word);

        }
        cout<<endl;

        i++;

    }

   // system("PAUSE");

    return 0;
}
